iT邦幫忙

2025 iThome 鐵人賽

DAY 24
0
Cloud Native

與雲原生精靈共舞:APISIX使用者的兩年旅程系列 第 24

Ch17 - APISIX x Keycloak:為 K8S Dashboard 部署「特勤門禁」—— Edge Gateway SSO 實戰

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20251008/20112470BH5iyRUNtP.png

身份驗證守門人」一章最後提到,如果上游服務節點有其他路徑可以鑽,那麼一切保護如同虛設。其實目前就有一個流行環境,天然的就隔離了內外流量----是的,就是Kubernetes(K8S)。在K8S環境外部要存取K8S內服務,通常需要透過port-forwardproxyService物件的方式。這一章分享透過Apache APISIX作爲K8S Service,配合身份驗證存取K8S Dashboard的方式。

這種在邊界的API網關,有時又被稱作「Edge Gateway」。
不過,通常來說,存取K8S環境更實務做法會透過Ingress和Ingress Controller的方式處理。但依我理解上也不完全不需要Service。

準備K8S環境和Dashboard服務

K8S環境建立並不是本系列重點,此處直接使用minikube快速建立環境。以此章Lab提供給minikube的backend使用docker,建立兩個節點的K8S環境:

minikube start --nodes 2

https://ithelp.ithome.com.tw/upload/images/20251008/20112470yaMZpCZ0dD.png

以我建立的兩個服務節點IP是192.168.49.2192.168.49.3,之後會透過這兩個IP存取K8S環境內服務。

minikube        192.168.49.2
minikube-m02    192.168.49.3

然後也直接透過minikube建立dashboard服務:

minikube dashboard enable dashboard

可以進一步啓用metrics-server

minikube addons enable metrics-server

https://ithelp.ithome.com.tw/upload/images/20251008/201124709wKDgMcI7F.png

可以透過minikube service listkubectl get service -A -o wide建立的Service。

https://ithelp.ithome.com.tw/upload/images/20251008/20112470F36d6fCbbs.png

使用minikube dashboard --urlkubectl port-forward取得連接瀏覽Dashboard。

https://ithelp.ithome.com.tw/upload/images/20251008/20112470oVeIlnDVp4.png

老實說我有點意外用minikube addon建立的dashboard服務不需要輸入token...

建立Keycloak服務

透過docker compose建立keycloak服務:

services:
  keycloak:
    image: "quay.io/keycloak/keycloak:22.0.5"
    restart: unless-stopped
    network_mode: host
    environment:
      TZ: "Asia/Taipei"
      KC_HTTP_ENABLED: "true"
      # KC_HTTPS_PORT: 8444
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin
      KC_HOSTNAME_STRICT: "false"
      KC_HTTP_RELATIVE_PATH: "/auth"
    command: ['start-dev', '--transaction-xa-enabled', 'false']

雖然多少變化有點多了,不過Keycloak可以參考「用Keycloak學習身份驗證與授權」。建立User bob、Client ID k8s-lab。Client ID需要啓用Client authentication以取得Client Secret,並且加上允許的Redirect URI: http://192.168.49.2:30080/*http://192.168.49.3:30080/*。這會是K8S服務使用的位置,也就是minikube建立的兩個節點IP。

在K8S建立APISIX服務

接下來的K8S資源會建立在apisix的命名空間,先建立該命名空間:

kubectl create ns apisix

透過ConfigMap建立apisix_config/config.yaml檔案:

apiVersion: v1
kind: ConfigMap
metadata:
  name: apisix-conf
  namespace: apisix
data:
  config.yaml: |-
    deployment:
      role: data_plane
      role_data_plane:
        config_provider: yaml
    apisix:
      node_listen: 9080             # APISIX listening port
      enable_heartbeat: true

不同的是這次Lab使用靜態檔案方式獨立部署。所以需要另外準備一份apisix.yaml

注意:檔案必須是#END結尾

apiVersion: v1
kind: ConfigMap
metadata:
  name: apisix-route
  namespace: apisix
data:
  apisix.yaml: |-
    routes: #for example
      - 
        uris:
        - / 
        - /*
        upstream:
          nodes:
            "kubernetes-dashboard.kubernetes-dashboard.svc.cluster.local:80": 1
          scheme: http
          type: roudrobin
        plugins:
          openid-connect:
            client_id: k8s-lab
            client_secret: <填入Keycloak提供的Client Secret>
            discovery: https://127.0.0.1:8080/auth/realms/master/.well-known/openid-configuration
            realm: master
            bearer_only: false
            redirect_uri: /middle/callback            
            logout_path: /middle/logout
            access_token_in_authorization_header: true
            ssl_verify: false
            unauth_action: pass
    #END

只設定了一組路由,其反向代理K8S在kubernetes-dashboard命名空間的kubernetes-dashboard服阿。特別留意openid-connect Plugin部分,填入Keycloak服務資訊。注意redirect_uri不能是真實存在的端點,這個位置會被APISIX使用。

然後準備Deployment或Daemon,並將這兩份ConfigMap掛上:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: apisix
  namespace: apisix
  labels:
    app.kubernetes.io/name: apisix
spec:
  replicas: 2
  selector:
    matchLabels:
      app.kubernetes.io/name: apisix
  template:
    metadata:
      labels:
        app.kubernetes.io/name: apisix
    spec:
      containers:
        - name: apisix
          image: "apache/apisix:3.2.2-debian"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 9080
              protocol: TCP
            - name: tls
              containerPort: 9443
              protocol: TCP
            - name: admin
              containerPort: 9180
              protocol: TCP
          readinessProbe:
            failureThreshold: 6
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            tcpSocket:
              port: 9080
            timeoutSeconds: 1
          lifecycle:
            preStop:
              exec:
                command:
                - /bin/sh
                - -c
                - "sleep 30"
          volumeMounts:
            - mountPath: /usr/local/apisix/conf/config.yaml
              name: apisix-config
              subPath: config.yaml
            - mountPath: /usr/local/apisix/conf/apisix.yaml
              name: apisix-route
              subPath: apisix.yaml
          resources: {}
      volumes:
        - configMap:
            name: apisix-conf
          name: apisix-config
        - configMap:
            name: apisix-route
          name: apisix-route

然後是Servcie:

apiVersion: v1
kind: Service
metadata:
  name: apisix
  namespace: apisix
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: apisix
  externalTrafficPolicy: Local
  ports:
    - name: http
      port: 9080
      nodePort: 30080
    - name: https
      port: 9443
      nodePort: 30443

這裏使用的類型是NodePort,之後可以透過http://192.168.49.2:30080/*http://192.168.49.3:30080/*存取APISIX服務。在一切完成以後,瀏覽這兩個位置,應該會先跳到Keycloak進行身份驗證。使用bob帳號登入後就可以進入Dashboard服務。

其實我原本想要在進一步示範設定K8S的api-server,使其接受OIDC提供的token與群組,讓不同的Keycloak登入者有不一樣的存取權限。
不過沒想到minikube addon建立的dashboard服務並不需要使用token。就算我把--enable-skip-login--disable-settings-authorizer拿掉也是一樣。

雖然後續透過helm安裝官方的dashboard倒是可以。但要求OIDC-Provider必須是HTTPS。
恩...還有很多設置需要處理Orz...有時間有機會再分享啦XD!
(之前建立K8S環境是使用kubeadm建立的。不知道microk8s的dashboard又是如何?)


雖然我接觸時間不多、接觸也不深。不過也還是略懂一些掌舵技術的。
https://ithelp.ithome.com.tw/upload/images/20251008/20112470jzU4nZiVxK.jpg


上一篇
Ch16 - 身份驗證守門人,APISIX保護上游的兩種基本方式:Key-Auth和Basic-Auth
系列文
與雲原生精靈共舞:APISIX使用者的兩年旅程24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言